package com.hncboy.chatgpt.front.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.hncboy.chatgpt.base.config.ChatConfig;
import com.hncboy.chatgpt.base.domain.entity.ChatCustomerDO;
import com.hncboy.chatgpt.base.domain.mongodb.VerificationCode;
import com.hncboy.chatgpt.base.util.DateUtil;
import com.hncboy.chatgpt.base.util.StrUtil;
import com.hncboy.chatgpt.front.domain.request.VerifySecretRequest;
import com.hncboy.chatgpt.front.domain.vo.ApiModelVO;
import com.hncboy.chatgpt.front.domain.vo.ChatCustomerVO;
import com.hncboy.chatgpt.front.domain.vo.ChatOrderVO;
import com.hncboy.chatgpt.front.mongodb.VerificationCodeMapper;
import com.hncboy.chatgpt.front.service.*;
import com.mysql.cj.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

/**
 * @author hncboy
 * @date 2023/3/22 20:05
 * 鉴权相关业务实现类
 */
@Slf4j
@Service
public class AuthServiceImpl implements AuthService {

    private static String phonePattern = "/^1[3|4|5|7|8][0-9]{9}$/";
    private static String emailPattern = "/^[A-Za-z\\d]+([-_.][A-Za-z\\d]+)*@([A-Za-z\\d]+[-.])+[A-Za-z\\d]{2,4}$/";
    @Value("${chat.limits}")
    Integer limits;
    @Resource
    VerificationCodeMapper verificationCodeMapper;
    @Resource
    private ChatConfig chatConfig;
    @Resource
    private CustomerService customerServiceImpl;
    @Resource
    private ChatOrderService chatOrderService;
    @Resource
    private EmailService emailServiceImpl;

    @Override
    public ChatCustomerVO verifySecretKey(VerifySecretRequest verifySecretRequest) throws Exception {
        String loginName = verifySecretRequest.getLoginName();
        String authorizationCode = verifySecretRequest.getAuthorizationCode();
        String invitationCode = verifySecretRequest.getInvitationCode();
        log.info("起始线为：  ======================================");
        log.info("验证码为：  " + authorizationCode);
        log.info("邮箱号为：  " + loginName);
        log.info("结束线为：  ======================================");

        //邀请者--发起邀请给别人------inviter
        //被邀请者--接受邀请，并填写邀请码注册的用户-------invitee

        //1、核对验证码是否失效
        //2、未失效，判断是否有邀请码，如有邀请码，判断是否是老用户填写
        //3、新增新用户，生成6位随机邀请码，设置已被邀请，并处理邀请者奖励，邀请次数加1，
        //4、处理邀请者奖励，查询邀请用户的总邀请次数，判断是否达到额外赠送规则
        //5、还需要查询邀请者会员到期时间，有会员则获取最终到期时间，在此基础上新增订单，
        //6、没有会员的，则直接新增即可

        //邀请规则：1个人奖励1天，10个人额外送5天，20个人额外送12天，30个人额外送20天，60个人额外送45天，90个人额外送90天
        VerificationCode verificationCode = verificationCodeMapper.selectByEmailAndCode(loginName, authorizationCode);
        log.info("mongodb中保存的验证码为：{}", JSONUtil.toJsonStr(verificationCode));
        if (BeanUtil.isNotEmpty(verificationCode)) {
            long difference = new Date().getTime() - verificationCode.getEnd().getTime();
            if (difference > 0) {
                throw new RuntimeException("验证码失效");
            } else {
                ChatCustomerDO customer = customerServiceImpl.getCustomer(loginName);
                if (Objects.isNull(customer)) {
                    //注册用户
                    //生成6位随机邀请码，并查询邀请码是否已存在，存在则再次生成
                    String randomCode = StrUtil.getRanStr(6);
                    for (; true; ) {
                        //查询邀请码是否存在
                        ChatCustomerDO invitedCustomer = customerServiceImpl.getCustomerByInvitationCode(randomCode);
                        if (Objects.isNull(invitedCustomer)) {
                            //不存在
                            break;
                        }
                        //存在，生成下一个
                        randomCode = StrUtil.getRanStr(6);
                    }

                    //是否被邀请
                    int isInvited = 0;
                    //记录邀请者信息
                    ChatCustomerDO invitedCustomer = null;
                    //判断是否有填写邀请码
                    if (!StringUtils.isNullOrEmpty(invitationCode)) {
                        //有，先查询邀请码是否有效，再生成新用户（邮箱、随机码、已被邀请）
                        invitedCustomer = customerServiceImpl.getCustomerByInvitationCode(invitationCode);
                        if (!Objects.isNull(invitedCustomer)) {
                            //存在邀请者，有效邀请码
                            isInvited = 1;
                        }
                    }

                    //注册新用户
                    ChatCustomerVO chatCustomerVO = customerServiceImpl.addCustomer(loginName, randomCode, isInvited);
                    //邀请成功，奖励机制启动
                    if (isInvited == 1) {
                        /** 对邀请者进行奖励机制 */
                        //获取邀请次数，加1保存
                        int invitedCount = invitedCustomer.getInvitedCount() + 1;
                        invitedCustomer.setInvitedCount(invitedCount);

                        //邀请奖励订单需要的会员起始时间与结束时间，判断累计奖励后最终用于修改邀请者到期时间
                        Date orderVipStartTime, orderVipEndTime;

                        //奖励天数
                        int rewardsDays = 1;

                        //（1）查询邀请者信息，是否会员，存在则查询会员到期时间，并记录
                        if (invitedCustomer.getIsVip() == 1) {
                            //是会员，那订单的开始时间获取旧会员到期时间即可
                            orderVipStartTime = invitedCustomer.getVipEndTime();
                            orderVipEndTime = DateUtil.offsetDay(invitedCustomer.getVipEndTime(), rewardsDays);
                        } else {
                            //非会员
                            orderVipStartTime = new Date();
                            orderVipEndTime = DateUtil.offsetDay(new Date(), rewardsDays);
                            //修改邀请者信息，添加会员状态与开始时间
                            invitedCustomer.setIsVip(1);
                            invitedCustomer.setVipStartTime(orderVipStartTime);
                        }

                        //（2）新增1天会员时长的邀请奖励订单
                        ChatOrderVO chatOrderVO = new ChatOrderVO();
                        chatOrderVO.setCustomerId(invitedCustomer.getId());
                        chatOrderVO.setType(1);
                        chatOrderVO.setLevel(1);
                        chatOrderVO.setOrderType(2);
                        chatOrderVO.setInviteeId(chatCustomerVO.getId());
                        chatOrderVO.setInviteeName(chatCustomerVO.getNickName());
                        chatOrderVO.setRewardsDays(rewardsDays);
                        chatOrderVO.setStatus(1);
                        chatOrderVO.setBegin(orderVipStartTime);
                        chatOrderVO.setEnd(orderVipEndTime);
                        chatOrderService.createOrder(chatOrderVO);

                        //（3）判断当前是否满足额外赠送条件，满足则再新增对应时长，生成两条记录存储再订单表，方便核对
                        //修改订单续费类型、奖励天数、会员开始和到期时间，清空被邀请者id和name
                        switch (invitedCount) {
                            case 10:
                                rewardsDays = 5;
                                break;
                            case 20:
                                rewardsDays = 12;
                                break;
                            case 30:
                                rewardsDays = 20;
                                break;
                            case 60:
                                rewardsDays = 45;
                                break;
                            case 90:
                                rewardsDays = 90;
                                break;
                        }

                        if (rewardsDays != 1) {
                            //获得累计奖励
                            chatOrderVO.setOrderType(3);
                            chatOrderVO.setRewardsDays(rewardsDays);
                            //累计奖励订单的会员起始时间是邀请订单的会员到期时间
                            chatOrderVO.setBegin(orderVipEndTime);
                            //累计奖励订单的会员到期时间是邀请订单的会员到期时间加奖励天数
                            orderVipEndTime = DateUtil.offsetDay(orderVipEndTime, rewardsDays);
                            chatOrderVO.setEnd(orderVipEndTime);
                            chatOrderVO.setInviteeId(null);
                            chatOrderVO.setInviteeName(null);
                            chatOrderService.createOrder(chatOrderVO);
                        }

                        //修改邀请者的会员到期时间
                        invitedCustomer.setVipEndTime(orderVipEndTime);
                        customerServiceImpl.saveOrUpdate(invitedCustomer);

                        /** 对被邀请者进行奖励机制 */
                        //被邀请者属于新注册，非会员，会员时间由当前起始
                        orderVipStartTime = new Date();
                        orderVipEndTime = DateUtil.offsetDay(new Date(), rewardsDays);
                        //修改被邀请者信息，添加会员状态与开始结束时间
                        ChatCustomerDO chatCustomerDO = customerServiceImpl.getCustomer(chatCustomerVO.getId());
                        chatCustomerDO.setIsVip(1);
                        chatCustomerDO.setVipStartTime(orderVipStartTime);
                        chatCustomerDO.setVipEndTime(orderVipEndTime);
                        customerServiceImpl.saveOrUpdate(chatCustomerDO);
                        //奖励天数为1
                        rewardsDays = 1;
                        chatOrderVO.setCustomerId(chatCustomerDO.getId());
                        chatOrderVO.setType(1);
                        chatOrderVO.setLevel(1);
                        chatOrderVO.setOrderType(4);
                        chatOrderVO.setInviteeId(invitedCustomer.getId());
                        chatOrderVO.setInviteeName(invitedCustomer.getNickName());
                        chatOrderVO.setRewardsDays(rewardsDays);
                        chatOrderVO.setStatus(1);
                        chatOrderVO.setBegin(orderVipStartTime);
                        chatOrderVO.setEnd(orderVipEndTime);
                        chatOrderService.createOrder(chatOrderVO);

                    }
                    return chatCustomerVO;
                } else {
                    //登录
                    return customerServiceImpl.infoCustomer(customer.getId());
                }
            }
        } else {
            throw new RuntimeException("验证码错误");
        }
    }

    @Override
    public ApiModelVO getApiModel() {
        ApiModelVO apiModelVO = new ApiModelVO();
        apiModelVO.setAuth(chatConfig.hasAuth());
        apiModelVO.setModel(chatConfig.getApiTypeEnum());
        apiModelVO.setAuthSecretKey(chatConfig.getAuthSecretKey());
        return apiModelVO;
    }


    @Override
    public ChatCustomerVO infoCustomer(Long customerId) {
        return customerServiceImpl.infoCustomer(customerId);
    }

    @Override
    public boolean updateCustomer(ChatCustomerDO chatCustomerDO) {
        return customerServiceImpl.saveOrUpdate(chatCustomerDO);
    }

    @Override
    public VerificationCode send(VerifySecretRequest verifySecretRequest) {
        return emailServiceImpl.send(verifySecretRequest.getLoginName());
    }

}
